package ar.camera.renderer.extend;

import java.util.ArrayList;
import java.util.List;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import ar.camera.globject.Intersection;
import ar.camera.globject.RoadSegment;
import ar.camera.pojo.GLLocation;
import ar.camera.pojo.GLPoint;
import ar.camera.pojo.GeoLocation;
import ar.globals.Globals;
import ar.utils.GLIconUtils;
import ar.utils.LocationUtils;

public class RouteRenderer implements GLSurfaceView.Renderer {
	private final Context context;
	private List<RoadSegment> segments = new ArrayList<RoadSegment>();
	private List<Intersection> directions = new ArrayList<Intersection>();
	private GLLocation curr;
	private GLLocation originGL;
	private List<GLLocation> listLcts;

	float eyeZ = 0;

	public RouteRenderer(Context context) {
		this.context = context;
	}

	public void onSurfaceCreated(GL10 gl, EGLConfig config) {

		// Define the lighting
		float lightAmbient[] = new float[] { 0.5f, 0.5f, 0.5f, 0.5f };
		float lightDiffuse[] = new float[] { 1, 1, 1, 1 };
		float[] lightPos = new float[] { 1, 1, 1, 1 };
		gl.glEnable(GL10.GL_LIGHTING);
		gl.glEnable(GL10.GL_LIGHT0);
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0);
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);

		float matAmbient[] = new float[] { 1, 1, 1, 1 };
		float matDiffuse[] = new float[] { 1, 1, 1, 1 };
		gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, matAmbient, 0);
		gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, matDiffuse, 0);

		gl.glEnable(GL10.GL_DEPTH_TEST);
		gl.glDepthFunc(GL10.GL_LEQUAL);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl.glEnable(GL10.GL_TEXTURE_2D);

		Globals.routeOriginGeo = Globals.currentGeoLocation;
		originGL = LocationUtils
				.convertFromGeoLocationToGLLocation(Globals.routeOriginGeo);
		List<GeoLocation> geos = new ArrayList<GeoLocation>();
		for (int i = 0; i < Globals.listOfRoutePoints.size(); i++) {
			GeoLocation g = new GeoLocation(
					Globals.listOfRoutePoints.get(i).mLatitude,
					Globals.listOfRoutePoints.get(i).mLongitude, "");
			geos.add(g);
		}
		listLcts = LocationUtils
				.convertFromListOfGeoLocationsToListOfGLLocations(geos,
						Globals.routeOriginGeo, 500000);
		for (int i = 0; i < listLcts.size() - 1; i++) {
			GLLocation l1 = listLcts.get(i);
			GLLocation l2 = listLcts.get(i + 1);

			RoadSegment segment = new RoadSegment(l1, l2);
			segment.loadGLTexture(gl, context);
			segments.add(segment);
		}

		for (int i = 1; i < listLcts.size() - 1; i++) {
			GLLocation l1 = listLcts.get(i);
			GLLocation l2 = listLcts.get(i + 1);

			Intersection dr = new Intersection(l1, l2);
			dr.loadGLTexture(gl, context);
			directions.add(dr);
		}
	}

	public void onSurfaceChanged(GL10 gl, int width, int height) {
		gl.glViewport(0, 0, width, height);
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
	}

	public void onDrawFrame(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();

		float ratio = 800 / 480;
		GLU.gluPerspective(gl, 45.0f, ratio, 0.1f, 1000f);

		curr = LocationUtils
				.convertFromGeoLocationToGLLocation(Globals.currentGeoLocation);
		curr.x = (curr.x - originGL.x) * 500000;
		curr.z = (curr.z - originGL.z) * 500000;

		GLPoint cam = new GLPoint(curr.x, 0, curr.z + 20);
		float tmp = Globals.routeAzimut;
		tmp = (float) ((tmp + 90) * Math.PI / 180);
		GLPoint center = new GLPoint(curr.x, 0f, curr.z);
		cam = GLIconUtils.rotateY(cam, center, -tmp);
		GLU.gluLookAt(gl, curr.x, 2.5f, curr.z, cam.x, 0, cam.z, 0, 1, 0);

		for (RoadSegment seg : segments) {
			seg.draw(gl);
		}
		for (Intersection dr : directions) {
			dr.draw(gl);
		}
	}
}